/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package expertos;

import DTOs.DTOMaterial;
import entidadesNegocio.Material;
import entidadesNegocio.TipoMaterial;
import excepciones.ExpertoMaterialesException;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import persistencia.Fachada;

/**
 *
 * @author diego
 */
public class ExpertoMateriales extends Experto {

    /**
     * Busca materiales según los datos ingresados en dtoBusqueda
     * si no encuentra lanza ExpertoMaterialesExeption
     * @param dtoBusqueda
     * @return List<Material>
     * @throws ExpertoMaterialesException 
     */
    public List<Material> buscarMateriales(DTOMaterial dtoBusqueda) throws ExpertoMaterialesException {
        List<Material> materialesEncontrados = null;
        if (dtoBusqueda == null) {
            materialesEncontrados = Fachada.getInstancia().buscar(Material.class, null);
        } else {
            Criteria criterio = Fachada.getInstancia().crearCriterio(Material.class);
            if (dtoBusqueda.getCodigo().length() > 0) {
                criterio.add(Restrictions.like("codigoMaterial", "%"+dtoBusqueda.getCodigo()+"%"));
            }
            if (dtoBusqueda.getNombre().length() > 0) {
                criterio.add(Restrictions.like("nombreMaterial", "%" + dtoBusqueda.getNombre() + "%").ignoreCase());
            }
            if (dtoBusqueda.getTipo().length() > 0) {
                criterio.createAlias("tipoMaterial", "tipoMat");
                criterio.add(Restrictions.like("tipoMat.nombreTipoMaterial", "%" + dtoBusqueda.getTipo() + "%").ignoreCase());
            }
            criterio.addOrder(Order.asc("codigoMaterial"));
            materialesEncontrados = Fachada.getInstancia().buscar(Material.class, criterio);
        }

        if (materialesEncontrados.isEmpty()) {
            throw new ExpertoMaterialesException("No se han encontrado materiales para los datos ingresados");
        }

        return materialesEncontrados;
    }
    
    public void eliminarMaterial(Material material) throws ExpertoMaterialesException{
        material.setEliminado(Boolean.TRUE);
        try {
            Fachada.getInstancia().guardar(material);
        } catch (Exception ex) {
            throw new ExpertoMaterialesException("Error al elimnar Material");
        }
    }

    /**
     * Guarda un nuevo material
     * @param material
     * @throws ExpertoMaterialesException 
     */
    public void guardar(Material material) throws ExpertoMaterialesException {
        if (materialInvalido(material)) {
            throw new ExpertoMaterialesException("Faltan completar Campos");
        }
        try {
            Fachada.getInstancia().guardar(material);
        } catch (Exception ex) {
            throw new ExpertoMaterialesException("Error al guardar Material");
        }
    }

    /**
     * Busca una lista de todos los tipos de materiales
     * @return List<TipoMaterial>
     */
    public List<TipoMaterial> buscarTiposMateriales() {
        List<TipoMaterial> tiposEncontrados = null;
        Criteria criterio = Fachada.getInstancia().crearCriterio(TipoMaterial.class);
        criterio.addOrder(Order.asc("codigoTipoMaterial"));
        tiposEncontrados = Fachada.getInstancia().buscar(TipoMaterial.class, criterio);
        return tiposEncontrados;
    }

    /**
     * Regresa "true" si el material ingresado contiene algun campo vacío
     * @param material
     * @return boolean
     */
    private boolean materialInvalido(Material material) {
        //TODO: CORREGIR: Al guardar un material nuevo, si en unidad agregan letras el sistema falla
        if (material.getCodigoMaterial().length() == 0) {
            return true;
        } else if (material.getNombreMaterial().length() == 0) {
            return true;
        } else if (material.getTamanioUnidadMaterial() == 0) {
            return true;
        } else if (material.getUnidadMedidaMaterial().length() == 0) {
            return true;
        } else if (material.getTipoMaterial() == null) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Guarda un nuevo tipo de material
     * @param nuevoTipo
     * @throws ExpertoMaterialesException 
     */
    public void guardarNuevoTipo(TipoMaterial nuevoTipo) throws ExpertoMaterialesException {
        if (tipoMatInvalido(nuevoTipo)) {
            throw new ExpertoMaterialesException("Faltan completar Campos");
        }
        try {
            //TODO: al guardar un nuevo tipo, debo saber si esta actualizando y si actualizo el codigo, debe actualizar 
            //el codigo de los materiales
            //verificar que no sea vacio
            Fachada.getInstancia().guardar(nuevoTipo);
        } catch (Exception ex) {
            throw new ExpertoMaterialesException("Error al guardar Material");
        }
    }

    
    private boolean tipoMatInvalido(TipoMaterial nuevoTipo) {
        if (nuevoTipo.getCodigotipomaterial().length() == 0) {
            return true;
        } else if (nuevoTipo.getNombretipomaterial().length() == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Elimina el tipo de material pasado como parametro
     * @param tipoMat
     * @throws ExpertoMaterialesException 
     */
    public void eliminarTipoMat(TipoMaterial tipoMat) throws ExpertoMaterialesException {
        tipoMat.setEliminado(true);
        try {
            Fachada.getInstancia().guardar(tipoMat);
        } catch (Exception ex) {
            throw new ExpertoMaterialesException("Error al eliminar Tipo de Material");
        }
    }

    /**
     * Genera un codigo para el tipo de material seleccionado
     * @param tipoMaterial
     * @return 
     */
    public String generarCodigoMaterial(TipoMaterial tipoMaterial) {
        String nuevoCodigo = "";
        List<Material> materiales = new ArrayList<Material>();
        
        //busca todos los materiales del tipo seleccionado
        Criteria criterio = Fachada.getInstancia().crearCriterio(Material.class);
        criterio.createAlias("tipoMaterial", "tipoMat");
        criterio.add(Restrictions.like("tipoMat.nombreTipoMaterial", "%" + tipoMaterial.getNombretipomaterial() + "%").ignoreCase());
        criterio.addOrder(Order.desc("codigoMaterial"));
        materiales = Fachada.getInstancia().buscar(Material.class, criterio);
        if(materiales.isEmpty()){
            return tipoMaterial.getCodigotipomaterial().split("-")[0]+"-"+"0001";
        }
        int ultimoCodigo = Integer.valueOf(materiales.get(0).getCodigoMaterial().split("-")[1]);
        ultimoCodigo++;
        nuevoCodigo = String.valueOf(ultimoCodigo);
        while(nuevoCodigo.length() < 4){
            nuevoCodigo = "0"+nuevoCodigo;
        }
        return tipoMaterial.getCodigotipomaterial().split("-")[0]+"-"+nuevoCodigo;
    }
}
